package com.pvdnc.xdynamic.pluginize;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.PopupWindow;

import androidx.appcompat.app.AlertDialog;

import com.pvdnc.dxhook.DxHook;
import com.pvdnc.dxhook.HookCallback;
import com.pvdnc.dxhook.ReplaceCallback;
import com.pvdnc.dxhook.XHookManager;
import com.pvdnc.xdynamic.loader.PackageParserUtils;
import com.pvdnc.xdynamic.loader.mirror.PackageParser;
import com.pvdnc.xdynamic.loader.mirror.android.app.ActivityThread;
import com.pvdnc.xdynamic.loader.module.XModuleManager;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

public class ActivityChooser {
    private static final String TAG=ActivityChooser.class.getSimpleName();

    private static final AtomicReference<ActivityChooser> sInstance=new AtomicReference<>();

    public static void systemReady(Context context){
        sInstance.set(new ActivityChooser(context));
    }

    public static ActivityChooser get(){
        return sInstance.get();
    }

    private Context mContext;
    private ActivityChooser(Context context){
        mContext=context;
    }

    public List<ActivityInfo> findFreeActivity(Object pkg) throws Exception {
        List<ActivityInfo> activityInfoList=PackageParserUtils.getActivityInfoList(pkg);
        Object activityThread=ActivityThread.sCurrentActivityThread;
        try {
            Map<IBinder,Object> tokenRecordMap=ActivityThread.mActivities.get(activityThread);
            Iterator<ActivityInfo> itor=activityInfoList.iterator();
            while (itor.hasNext()){
                ActivityInfo ai=itor.next();
                for (Object record:tokenRecordMap.values()){
                    Activity activity= ActivityThread.ActivityClientRecord.activity.get(record);
                    String localClassName=activity.getLocalClassName();
                    Log.d(TAG,"found running activity:"+localClassName);
                    if(ai.name.equals(localClassName)){
                        itor.remove();
                    }
                }
            }
            return activityInfoList;
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    public void hookNewActivity() throws Exception {
        Method method= Instrumentation.class.getDeclaredMethod("callActivityOnCreate", Activity.class, Bundle.class);
        XHookManager.hookMethod(mContext,method,new ReplaceCallback(){
            @Override
            public void afterHookedMethod(Method oldMethod, Object thisRef, Object[] args) {
                super.afterHookedMethod(oldMethod, thisRef, args);
                final Activity activity= (Activity) args[0];
                Log.d(TAG,"after call onCreate for activity:"+activity);
                showDialog(activity);
            }
        });
    }

    private void showDialog(final Activity activity){
        AlertDialog.Builder builder=new AlertDialog.Builder(activity);
        builder.setTitle("Pluginize");
        builder.setMessage("Pluginize dialog shown");
        builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Log.d(TAG,"attempt to finish activity:"+activity);
                activity.finish();
            }
        });
        builder.create().show();
    }
}
